﻿using System;
using System.Collections;
using OpenTK;
using Painter3D.RenderSys.RenderObject;

namespace Painter3D.RenderSys
{
    /// <summary>
    /// 可渲染物体都因该包含这一组件,注意init方法需要被调用
    /// </summary>
    public class Render : Component
    {
        /// <summary>
        /// 物体的顶点信息
        /// </summary>
        public VertexData vertexData;
        /// <summary>
        /// 物体的材质
        /// </summary>
        public Material Material
        {
            get => material;
            set
            {
                material = value;
                vertexData.BindData(material.shader.info.vertexRequestInfos);
            }
        }
        private Material material;
        /// <summary>
        /// 物体的渲染层级
        /// </summary>
        public RenderLayer layer = new RenderLayer("default");

        /// <summary>
        /// 构造一个渲染器
        /// </summary>
        /// <param name="vertexData">顶点数据</param>
        /// <param name="material">材质</param>
        /// <param name="transform">吸附节点</param>
        public Render(VertexData vertexData, Material material, Transform transform) : base(transform)
        {
            this.vertexData = vertexData ?? throw new ArgumentNullException(nameof(vertexData));
            this.Material = material ?? throw new ArgumentNullException(nameof(material));
        }

        public virtual void RenderOut(Matrix4 GlobalMat)
        {
            material.SetValue("moduleMat", GlobalMat);
            material.UploadData();
            vertexData.DrawData();
        }

        public override void Dispose()
        {
            vertexData.Dispose();
            base.Dispose();
        }

        public override string ToString()
        {
            return base.ToString() + "Layer:" + layer.ToString() + Environment.NewLine + "Shader:" + Material.shader.shaderName + Environment.NewLine;
        }

        /// <summary>
        /// 直接渲染物体，由于没有组件维护需要重复调用才能持续显示
        /// </summary>
        /// <param name="renderObject">被渲染物体的顶点数据</param>
        /// <param name="material">材质</param>
        /// <param name="moduleMat">模型矩阵</param>
        public static void RenderOut(VertexData renderObject, Material material, Matrix4 moduleMat)
        {
            renderObject.BindData(material.shader.info.vertexRequestInfos);
            material.SetValue("moduleMat", moduleMat);
            material.UploadData();
            renderObject.DrawData();
        }
    }
}
